﻿using System.Reflection;
using NVelocity;

namespace SW.Lite.Core.Template.NVelocity
{
    /// <summary>
    ///     <para>Class StaticClassHelper.</para>
    ///     <para>We donot sugguest use this too many times.Reflection is not not good for application.</para>
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class StaticClassHelper<T> : IDuck
    {
        /// <summary>
        ///     Defines the behavior when a property is read
        /// </summary>
        /// <param name="propName">Property name.</param>
        /// <returns>value back to the template</returns>
        public object GetInvoke(string propName)
        {
            var type = typeof(T);
            return type.InvokeMember(propName,
                BindingFlags.Public | BindingFlags.Static | BindingFlags.GetField | BindingFlags.GetProperty,
                null, null, new object[] { });
        }

        /// <summary>
        ///     Defines the behavior when a property is written
        /// </summary>
        /// <param name="propName">Property name.</param>
        /// <param name="value">The value to assign.</param>
        public void SetInvoke(string propName, object value)
        {
            typeof(T).InvokeMember(propName,
                BindingFlags.Public | BindingFlags.Static | BindingFlags.SetField | BindingFlags.SetProperty,
                null, null, new[] { value });
        }

        /// <summary>
        ///     Invokes the specified method.
        /// </summary>
        /// <param name="method">The method name.</param>
        /// <param name="args">The method arguments.</param>
        /// <returns>value back to the template</returns>
        public object Invoke(string method, params object[] args)
        {
            var type = typeof(T);
            return type.InvokeMember(method,
                BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod,
                null, null, args);
        }
    }
}